package com.jiangyao.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiangyao.common.constants.AdminUserConstants;
import com.jiangyao.common.constants.ConfigConstants;
import com.jiangyao.common.constants.SystemConstants;
import com.jiangyao.common.exception.ServerException;
import com.jiangyao.common.utils.MD5util;
import com.jiangyao.common.utils.StringUtils;
import com.jiangyao.dao.IClassInfoDao;
import com.jiangyao.dao.IOrgInfoDao;
import com.jiangyao.model.dto.ClassInfoDto;
import com.jiangyao.model.dto.backend.ClassInfoDTO;
import com.jiangyao.model.dto.backend.ClassInfoListPageDTO;
import com.jiangyao.model.entity.AdminUser;
import com.jiangyao.model.entity.AdminUserOrgClass;
import com.jiangyao.model.entity.ClassInfo;
import com.jiangyao.model.entity.OrgInfo;
import com.jiangyao.model.vo.AdminUserSessionVO;
import com.jiangyao.model.vo.backend.AdminUserBaseVO;
import com.jiangyao.model.vo.backend.ClassInfoExportVO;
import com.jiangyao.model.vo.backend.ClassInfoListVO;
import com.jiangyao.model.vo.backend.ClassInfoVO;
import com.jiangyao.model.vo.backend.OrgInfoBaseVO;
import com.jiangyao.service.AdminUserOrgClassService;
import com.jiangyao.service.AdminUserService;
import com.jiangyao.service.ClassInfoService;
import com.jiangyao.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 班级信息 服务实现类
 * </p>
 *
 * @author xiangyan
 * @since 2020-08-13
 */
@Service
@Slf4j
public class ClassInfoServiceImpl extends BaseServiceImpl<IClassInfoDao, ClassInfo> implements ClassInfoService {

	@Autowired
	private IClassInfoDao classInfoDao;

	@Autowired
	private DozerBeanMapper dozerBeanMapper;

	@Autowired
	private IOrgInfoDao orgInfoDao;

	@Autowired
	private AdminUserService adminUserService;

	@Autowired
	private AdminUserOrgClassService adminUserOrgClassService;

	@Autowired
	private ConfigService configService;

	@Override
	public List<ClassInfo> getOrgClassByParams(ClassInfoDto queryDto) {
		QueryWrapper<ClassInfo> params = new QueryWrapper<>();
		if (queryDto.getOrgId() > 0) {
			params.eq("org_id", queryDto.getOrgId());
		}
		if (StringUtils.isNotEmpty(queryDto.getClassName())) {
			params.like("class_name", queryDto.getClassName());
		}
		if (queryDto.getStatus() != null) {
			params.like("status", queryDto.getStatus());
		}
		return this.list(params);
	}

	@Override
	public Page<ClassInfoListVO> getListPage(ClassInfoListPageDTO listPageDTO) {
		// 登录用户信息
		AdminUserSessionVO adminUserSessionVO = getAdminLoginSession();
		// 当前登录用户管理的班级ID集合(业务数据权限)
		listPageDTO.setClassIdList(adminUserSessionVO.getClassIdList());

		Page<ClassInfoListVO> page = new Page<>(listPageDTO.getPageNo(), listPageDTO.getPageSize());
		classInfoDao.getListPage(page, listPageDTO);
		return page;
	}

	@Override
	public void add(ClassInfoDTO classInfoDTO) {
		// 获取组织
		OrgInfo orgInfo = orgInfoDao.selectById(classInfoDTO.getOrgId());
		if (orgInfo == null) {
			throw new ServerException(100, "组织不存在");
		}
		// 检查重名
		ClassInfo classInfoByOrgName = getOneByClassName(classInfoDTO);
		if (classInfoByOrgName != null) {
			throw new ServerException(100, "该组织下班级名已存在");
		}
		// 处理组织管理员,返回新的管理员ID
		Integer manageAdminUserId = handleManageAdmin(orgInfo, classInfoDTO);
		Date now = new Date();
		ClassInfo classInfo = dozerBeanMapper.map(classInfoDTO, ClassInfo.class);
		classInfo.setStatus(1);
		classInfo.setCreateTime(now);
		classInfo.setCreateAdminId(getLoginAdminUserId());
		classInfoDao.insert(classInfo);
		if (manageAdminUserId != null && manageAdminUserId > 0) {
			// 增加组织管理员
			AdminUserOrgClass adminUserOrgClass = new AdminUserOrgClass();
			adminUserOrgClass.setAdminId(manageAdminUserId);
			adminUserOrgClass.setOrgId(classInfo.getOrgId());
			adminUserOrgClass.setClassId(classInfo.getClassId());
			adminUserOrgClass.setCreateTime(now);
			adminUserOrgClassService.save(adminUserOrgClass);
		}
	}

	/**
	 * 根据组织ID、班级名获取班级
	 *
	 * @param classInfoDTO     组织DTO
	 * @return 结果
	 */
	private ClassInfo getOneByClassName(ClassInfoDTO classInfoDTO) {
		if (StringUtils.isBlank(classInfoDTO.getClassName())) {
			return null;
		}
		QueryWrapper<ClassInfo> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("org_id", classInfoDTO.getOrgId());
		queryWrapper.eq("class_name", classInfoDTO.getClassName());
		queryWrapper.eq("major", classInfoDTO.getMajor());
		queryWrapper.eq("grade", classInfoDTO.getGrade());
		queryWrapper.last(" LIMIT 1");
		return this.getOne(queryWrapper);
	}

	/**
	 * 处理班级管理员
	 *
	 * @param orgInfo      组织信息
	 * @param classInfoDTO 班级信息DTO
	 * @return 结果
	 */
	private Integer handleManageAdmin(OrgInfo orgInfo, ClassInfoDTO classInfoDTO) {
		Integer classId = classInfoDTO.getClassId();
		// 以前的管理员ID
		Integer preAdminUserId = null;
		Integer manageAdminUserId = classInfoDTO.getManageAdminUserId();
		// 编辑班级
		if (classId != null && classId != 0) {
			// 获取以前的管理员ID
			preAdminUserId = adminUserOrgClassService.getAdminUserId(null, classId);
			// 管理员没修改
			if (preAdminUserId != null && preAdminUserId.equals(manageAdminUserId)) {
				return manageAdminUserId;
			}
		}

		// 选择已有管理员
		if (manageAdminUserId != null && manageAdminUserId != 0) {
			AdminUser adminUser = adminUserService.getById(manageAdminUserId);
			if (adminUser == null || adminUser.getStatus() != 1) {
				throw new ServerException(100, "管理员不存在或不可用");
			}
		} else if (StringUtils.isNotEmpty(classInfoDTO.getManageLoginName()) || StringUtils.isNotEmpty(classInfoDTO.getManageName())) {
			// 新增管理员
			if (StringUtils.isEmpty(classInfoDTO.getManageLoginName())) {
				throw new ServerException(100, "管理员账号");
			}
			if (StringUtils.isEmpty(classInfoDTO.getManageName())) {
				throw new ServerException(100, "管理员姓名不能为空");
			}
			AdminUser adminUser = adminUserService.getByLoginName(classInfoDTO.getManageLoginName());
			if (adminUser != null) {
				throw new ServerException(100, "管理员账号已存在");
			}
			adminUser = AdminUser.builder().loginName(classInfoDTO.getManageLoginName()).adminName(classInfoDTO.getManageName())
					.password(MD5util.generateSymbol(AdminUserConstants.DEFAULT_PASSWORD)).phone(classInfoDTO.getManagePhone())
					.adminPhoto(SystemConstants.USER_HEAD_DEFAULT).status(1).createTime(new Date()).createAdminId(getLoginAdminUserId())
					.build();
			adminUserService.save(adminUser);
			manageAdminUserId = adminUser.getAdminId();
		}
		// 管理员角色权限
		if (manageAdminUserId != null) {
			List<Integer> roleIdList;
			// 学校
			if (orgInfo.getOrgType() == 1) {
				roleIdList = AdminUserConstants.SCHOOL_CLASS_ADMIN_ROLE_ID_LIST;
			} else {
				// 企业
				roleIdList = AdminUserConstants.ENTERPRISE_CLASS_ADMIN_ROLE_ID_LIST;
			}
			adminUserService.saveAdminRole(manageAdminUserId, roleIdList);
		}
		// 编辑班级，班级以前管理员不为空
		if (classId != null && preAdminUserId != null) {
			QueryWrapper<AdminUserOrgClass> queryWrapper = new QueryWrapper<>();
			queryWrapper.eq("class_id", classId);
			adminUserOrgClassService.remove(queryWrapper);
		}
		return manageAdminUserId;
	}

	@Override
	public void edit(ClassInfoDTO classInfoDTO) {
		ClassInfo classInfo = this.getById(classInfoDTO.getClassId());
		if (classInfo == null) {
			throw new ServerException(100, "该班级不存在");
		}
		// 修改班级名称，检查重名
		if (!classInfo.getClassName().equals(classInfoDTO.getClassName())) {
			ClassInfo classInfoByOrgName = getOneByClassName(classInfoDTO);
			if (classInfoByOrgName != null) {
				throw new ServerException(100, "班级名已存在");
			}
		}
		// 处理组织管理员,返回新的管理员ID
		Integer manageAdminUserId = handleManageAdmin(orgInfoDao.selectById(classInfo.getOrgId()), classInfoDTO);
		Date now = new Date();
		BeanUtils.copyProperties(classInfoDTO, classInfo, "orgId", "createTime", "createAdminId", "status");
		classInfo.setUpdateTime(now);
		classInfo.setUpdateAdminId(getLoginAdminUserId());
		classInfoDao.updateById(classInfo);

		// 获取以前的管理员ID
		Integer preAdminUserId = adminUserOrgClassService.getAdminUserId(null, classInfoDTO.getClassId());
		// 增加组织管理员 TODO
		if (manageAdminUserId != null && manageAdminUserId > 0 && (preAdminUserId == null || !preAdminUserId.equals(manageAdminUserId)) ) {
			AdminUserOrgClass adminUserOrgClass = new AdminUserOrgClass();
			adminUserOrgClass.setAdminId(manageAdminUserId);
			adminUserOrgClass.setOrgId(classInfo.getOrgId());
			adminUserOrgClass.setClassId(classInfo.getClassId());
			adminUserOrgClass.setCreateTime(now);
			adminUserOrgClassService.save(adminUserOrgClass);
		}
	}

	@Override
	public void editStatus(ClassInfoDTO classInfoDTO) {
		UpdateWrapper<ClassInfo> updateWrapper = new UpdateWrapper<>();
		updateWrapper.in("class_id", classInfoDTO.getClassIdList());
		updateWrapper.set("status", classInfoDTO.getStatus() != null ? classInfoDTO.getStatus() : 1);
		updateWrapper.set("update_time", new Date());
		updateWrapper.set("update_admin_id", getLoginAdminUserId());
		this.update(updateWrapper);
	}

	@Override
	public ClassInfoVO getDetail(ClassInfoDTO classInfoDTO) {
		ClassInfo classInfo = this.getById(classInfoDTO.getClassId());
		if (classInfo == null) {
			throw new ServerException(100, "该班级不存在");
		}
		ClassInfoVO classInfoVO = dozerBeanMapper.map(classInfo, ClassInfoVO.class);
		OrgInfo orgInfo = orgInfoDao.selectById(classInfo.getOrgId());
		if (orgInfo != null) {
			classInfoVO.setOrgInfo(dozerBeanMapper.map(orgInfo, OrgInfoBaseVO.class));
		}
		AdminUser adminUser = adminUserOrgClassService.getAdminUser(null, classInfo.getClassId());
		if (adminUser != null) {
			classInfoVO.setAdminUser(dozerBeanMapper.map(adminUser, AdminUserBaseVO.class));
		}
		return classInfoVO;
	}

	@Override
	public void export(HttpServletResponse response, ClassInfoListPageDTO listPageDTO) {
		try {
			// 登录用户信息
			AdminUserSessionVO adminUserSessionVO = getAdminLoginSession();
			// 当前登录用户管理的组织ID集合(业务数据权限)
			listPageDTO.setClassIdList(adminUserSessionVO.getClassIdList());

			Page<ClassInfoListVO> page = new Page<>(1L, Long.parseLong(configService.getValueFromCache(ConfigConstants.EXCEL_EXPORT_LIMIT)));
			page.setSearchCount(false);
			classInfoDao.getListPage(page, listPageDTO);
			if (CollectionUtils.isEmpty(page.getRecords())) {
				return;
			}
			// 导出租住列表集合
			List<ClassInfoExportVO> exportVOList = new ArrayList<>(page.getRecords().size());
			page.getRecords().forEach(vo -> {
				exportVOList.add(dozerBeanMapper.map(vo, ClassInfoExportVO.class));
			});
			String fileName = URLEncoder.encode("班级列表", "UTF-8");
			response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
			EasyExcel.write(response.getOutputStream(), ClassInfoExportVO.class).sheet("班级列表").doWrite(exportVOList);
		} catch (Exception e) {
			log.error("组织导出失败，error:{}", e.getMessage(), e);
		}
	}
}
